Introduction to the VIC-II
by Pasi 'Albert' Ojala ( ... )

The Video Interface Controller used in C64 have several different operating
modes and different graphical primitives. Basically there is a) character
mode, b) bitmap mode and c) movable objects that can be mixed with the
other graphics. These primitives can also be put into a more colorful mode,
but you lose half of the resolution in that process.


I. Standard Character Display Mode

In the character display mode, VIC fetches character pointers from video
matrix, which consists of 1000 8-bit bytes formatted as 25 rows of 40
characters each. The 8-bit character code implies 256 different characters
simultaneously onscreen.

Each character code can have an unique image, which consists of 8 bytes in
character memory. The position of the character memory can be moved with the
character base pointer and thus it is possible to have several character sets
simultaneosly in memory. One character memory is 2048 bytes.

In addition to the character code, each position in video matrix has an
associated color nybble (4 bits) in color memory ($D800-$DFFF). For each
zero-bit in the charset the background color from register $21 is displayed,
the color-nybble is used for the one-bit.


II. Character Multicolor Mode

In character multicolor mode, color selection is increased. Each byte is
fetched from the character memory just like in the standard character mode,
but they are interpreted differently. In this mode bytes are divided into
bit-pairs. For bit pair "00" the background color from register $21 is
displayed, background color #1 is used for bit pair "01" and background
color #2 for bit pair "10". The color nybble will define the color for bit
pair "11".

The highest bit in the color memory defines whether the character is to be
displayed in multicolor ("1") or in standard mode ("0"). Because of this,
only colors in the range from 0 to 7 are possible for bit pair "11". And since
two bits are required to specify one dot color, the character is now displayed
as a 4x8 matrix instead of the 8x8 matrix and the size of the dots are doubled
horizontally.


III. Extended Color Mode

The extended color mode allows the selection of one background color from four
possibilities for each character position in the normal 8x8 resolution. The
character image data is processed like in standard character mode, but the
two most significant bits in the character code (video matrix) are used to
select the right background color register. Only character images from 0 to 63
are accessible, because two of the most significant bits are used for the
background color selection.

Extended color mode and multicolor mode should not be selected simultaneosly,
because this will result a black screen. However, this is a very easy way to
hide something if needed.


IV. Standard Bit Map Mode

In bit map mode, a one-to-one correspondence exists between each displayed
dot and a memory bit. The bit map provides a resolution of 320H x 200V
individually controlled pixels. The video matrix is still accessed as in
character mode, but the data is interpreted as color data. When a bit is "0"
in the bit map data, the color from the lower nybble is selected. The
higher nybble from the video matrix is used for the bit "1".


V. Multicolor Bit Map Mode

In multicolor bit map mode two bits in the bit map memory determine the color
of one pixel. If the bit pair is "11", the color found from the color memory
is used. The background color is used for bit pair "00" and the video matrix
defines the colors for bit pairs "01" and "10". As it takes two bits to define
one pixel color, the horizontal resolution is halved to 160H x 200V.


VI. Movable Object Blocks (MOBs)

The movable object block is a special type of graphical object which can be
displayed independently from the other graphics. Each one of the MOBs can
be moved independently anywhere in the screen. Eight unique MOBs can be
displayed simulataniously, each defined by 64 bytes in memory which are
displayed as a 24 x 21 pixel array.

Each MOB can be selectively enabled (MnE="1") or disabled (MnE="0"). A MOB
is positioned via its X and Y position registers. Nine bits are needed to
define the vertical position and the most significant bits of all MOBs are
stored in the register $10. As X locations 23 to 347 and Y locations 50 to
249 are entirely visible on the screen, MOBs can be smoothly moved to an
off-screen position.

Each MOB has its own color register and a MOB can be displayed either in
standard or multicolor mode (MnMC="1"). As usually, multicolor mode gives
more colors, but halves the horizontal resolution. In multicolor mode bit
pair "00" is transparent, the MOB color register defines the color for pair
"10", and MOB multicolor registers give the colors for pairs "01" and "11".

MOBs can be selectively expanded in both directions. When MOB is expanded,
the pixel size also expands and it is still displayed as 24 x 21 matrix
(12 x 21 in multicolor mode).

MOB priorities define whether a MOB appears behind or on top of the character
or bit map graphics. A "1" in MnDP means MOB is displayed behind. MOB
collision registers may be used to detect if a non-transparent data of two
MOBs or a MOB and character or bitmap foreground data is colliding.

[Ed's Note: MOB's are Sprites. Commodore initially referred to them as MOB's
and still does in some areas.]


VII. Other features

The display screen may be blanked by setting the DEN bit to a "0". The entire
screen will be filled with the border color as set in register 32 ($20).
When the screen is blanked, VIC will need only transparent memory cycles and
the processor is not slowed down. However, MOB data is still fetched, if
the MOBs are not also disabled.

The normal display consists of 25 rows of 40 characters each. The display
window can be reduced to 24 rows and 38 characters. This has no effect on how
the data is interpreted, only the characters next to the border are covered
by the border. RSEL controls the number of rows ("1" for 25 rows) and CSEL
controls the number of columns ("1" for 40 columns).

The display data may be scrolled up to one character space in both vertical
and horizontal direction. Position of the screen is set with the 3 lowest
order (least significant) bits in registers 22 ($16) and 17 ($11).

Light pen latch is used to catch the position of the light pen when a pulse
is received in the LP pin. The value is latched only once in a frame.

The raster register is a dual-function register. A read from the raster
register returns the current raster position and a write to it will set the
raster compare value. When the written value and the current raster line
matches, a raster interrupt is generated if enabled. Raster register has its
most significant (9th) bit in register 17 ($11).

The interrupt register shows the status of the four sources of interrupt.
A corresponding bit will be set to "1" when an interrupt source has generated
an interrupt request. To enable an interrupt request to set the /IRQ output
to zero, the corresponding enable bit in register 26 ($1a) must be set to
"1". The interrupt latch may only be cleared by writing a "1" to the
desired latch in the interrupt register.

-----------------------------------------------------------------------------
VIC register map (Base address $d000)

Address DB7   DB6   DB5   DB4   DB3   DB2   DB1   DB0   Description
-------------------------------------------------------------------
00 $00  M0X7  M0X6  M0X5  M0X4  M0X3  M0X2  M0X1  M0X0  MOB 0 X-position
01 $01  M0Y7  M0Y6  M0Y5  M0Y4  M0Y3  M0Y2  M0Y1  M0Y0  MOB 0 Y-position
02 $02  M1X7  M1X6  M1X5  M1X4  M1X3  M1X2  M1X1  M1X0  MOB 1 X-position
03 $03  M1Y7  M1Y6  M1Y5  M1Y4  M1Y3  M1Y2  M1Y1  M1Y0  MOB 1 Y-position
04 $04  M2X7  M2X6  M2X5  M2X4  M2X3  M2X2  M2X1  M2X0  MOB 2 X-position
05 $05  M2Y7  M2Y6  M2Y5  M2Y4  M2Y3  M2Y2  M2Y1  M2Y0  MOB 2 Y-position
06 $06  M3X7  M3X6  M3X5  M3X4  M3X3  M3X2  M3X1  M3X0  MOB 3 X-position
07 $07  M3Y7  M3Y6  M3Y5  M3Y4  M3Y3  M3Y2  M3Y1  M3Y0  MOB 3 Y-position
08 $08  M4X7  M4X6  M4X5  M4X4  M4X3  M4X2  M4X1  M4X0  MOB 4 X-position
09 $09  M4Y7  M4Y6  M4Y5  M4Y4  M4Y3  M4Y2  M4Y1  M4Y0  MOB 4 Y-position
10 $0a  M5X7  M5X6  M5X5  M5X4  M5X3  M5X2  M5X1  M5X0  MOB 5 X-position
11 $0b  M5Y7  M5Y6  M5Y5  M5Y4  M5Y3  M5Y2  M5Y1  M5Y0  MOB 5 Y-position
12 $0c  M6X7  M6X6  M6X5  M6X4  M6X3  M6X2  M6X1  M6X0  MOB 6 X-position
13 $0d  M6Y7  M6Y6  M6Y5  M6Y4  M6Y3  M6Y2  M6Y1  M6Y0  MOB 6 Y-position
14 $0e  M7X7  M7X6  M7X5  M7X4  M7X3  M7X2  M7X1  M7X0  MOB 7 X-position
15 $0f  M7Y7  M7Y6  M7Y5  M7Y4  M7Y3  M7Y2  M7Y1  M7Y0  MOB 7 Y-position
16 $10  M7X8  M6X8  M5X8  M4X8  M3X8  M2X8  M1X8  M0X8  MSB of X-position

17 $11  RC8   ECM   BMM   DEN   RSEL  Y2    Y1    Y0    (See text)
18 $12  RC7   RC6   RC5   RC4   RC3   RC2   RC1   RC0   Raster register
19 $13  LPX8  LPX7  LPX6  LPX5  LPX4  LPX3  LPX2  LPX1  Light Pen X
20 $14  LPY7  LPY6  LPY5  LPY4  LPY3  LPY2  LPY1  LPY0  Light Pen Y
21 $15  M7E   M6E   M5E   M4E   M3E   M2E   M1E   M0E   MOB Enable
22 $16  -     -     RES   MCM   CSEL  X2    X1    X0    (See text)
23 $17  M7YE  M6YE  M5YE  M4YE  M3YE  M2YE  M1YE  M0YE  MOB Y-expand
24 $18  VM13  VM12  VM11  VM10  CB13  CB12  CB11  -     Memory Pointers
25 $19  IRQ   -     -     -     ILP   IMMC  IMBC  IRST  Interrupt Register
26 $1a  -     -     -     -     ELP   EMMC  EMBC  ERST  Enable Interrupt
27 $1b  M7DP  M6DP  M5DP  M4DP  M3DP  M2DP  M1DP  M0DP  MOB-DATA Priority
28 $1c  M7MC  M6MC  M5MC  M4MC  M3MC  M2MC  M1MC  M0MC  MOB Multicolor select
29 $1d  M7XE  M6XE  M5XE  M4XE  M3XE  M2XE  M1XE  M0XE  MOB X-Expand
30 $1e  M7M   M6M   M5M   M4M   M3M   M2M   M1M   M0M   MOB-MOB  Collision
31 $1f  M7D   M6D   M5D   M4D   M3D   M2D   M1D   M0D   MOB-DATA Collision

32 $20  -     -     -     -     EC3   EC2   EC1   EC0   Exterior Color
33 $21  -     -     -     -     B0C3  B0C2  B0C1  B0C0  Background #0 Color
34 $22  -     -     -     -     B1C3  B1C2  B1C1  B1C0  Background #1 Color
35 $23  -     -     -     -     B2C3  B2C2  B2C1  B2C0  Background #2 Color
36 $24  -     -     -     -     B3C3  B3C2  B3C1  B3C0  Background #3 Color
37 $25  -     -     -     -     MM03  MM02  MM01  MM00  MOB Multicolor #0
38 $26  -     -     -     -     MM13  MM12  MM11  MM10  MOB Multicolor #1

39 $27  -     -     -     -     M0C3  M0C2  M0C1  M0C0  MOB 0 Color
40 $28  -     -     -     -     M1C3  M1C2  M1C1  M1C0  MOB 1 Color
41 $29  -     -     -     -     M2C3  M2C2  M2C1  M2C0  MOB 2 Color
42 $2a  -     -     -     -     M3C3  M3C2  M3C1  M3C0  MOB 3 Color
43 $2b  -     -     -     -     M4C3  M4C2  M4C1  M4C0  MOB 4 Color
44 $2c  -     -     -     -     M5C3  M5C2  M5C1  M5C0  MOB 5 Color
45 $2d  -     -     -     -     M6C3  M6C2  M6C1  M6C0  MOB 6 Color
46 $2e  -     -     -     -     M7C3  M7C2  M7C1  M7C0  MOB 7 Color

MnX  = MOB n X position         MnY  = MOB n Y position
RC   = Raster compare register  ECM  = Extended color mode
MBB  = Bit map mode             DEN  = Display enable
RSEL = Row select               Y    = Screen Y position
LPX  = Light pen X position     LPY  = Light pen Y position
MnE  = MOB n Enable             RES  = Always set to zero!
MCM  = Multicolor mode          CSEL = Column select
X    = Screen X position        MnYE = MOB n Y expand
VM   = Video matrix pointer     CB   = Character base pointer
MnDP = MOB to data priority     MnMC = MOB n multicolor select
MnXE = MOB n X expand

